package Ui;

import java.awt.Point;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Semaphore;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;

/*
 * @author Roch San Buenaventura
 */

public class Piece {
	
	private int currentSpace_;
	int pixelX_, pixelY_;
	
	private Queue<Integer> moveFromTo;
	Integer oldS, newS;
	
	private final int TOTAL_SPACES = 40;
	
	private int pieceSeparation = DisplayAssembler.getSpaceWidth() / 2;
	private String name_;
	
	private PieceState state_;
	
	private JLabel icon_;
	int iconWidth = (DisplayAssembler.getSpaceWidth() * 2 / 3);
	int iconHeight = (60/55) * iconWidth;
	
	private Semaphore motionControl;
	
	final static long serialVersionUID = 20;
	
	public Piece(String name, int playerNum) {
		
		name_ = "MonopolyImages/New Tokens/" + name + ".png";
		currentSpace_ = 0;

		state_ = PieceLeft.Instance();
		
		icon_ = new JLabel();
		
		try {
			icon_.setIcon(new ImageIcon(Display.scaleImage(new FileInputStream(name_),
					iconWidth, iconHeight)));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
		icon_.setBounds(0,0,iconWidth,iconHeight);
		icon_.setVisible(true);
		
		if(playerNum == 1) {
			pixelX_ = DisplayAssembler.getTopLeftGo() + 2;
			pixelY_ = DisplayAssembler.getTopLeftGo()+ (int)(DisplayAssembler.getSpaceWidth() * .35);
			DisplayAssembler.getInstance().addComponent(icon_, new Point(pixelX_, 
					pixelY_), JLayeredPane.MODAL_LAYER);
		}
		
		else if(playerNum == 2) {
			pixelX_ = DisplayAssembler.getTopLeftGo() + 2;
			pixelY_ = DisplayAssembler.getTopLeftGo() + (int)(DisplayAssembler.getSpaceWidth() * .35) + pieceSeparation;
			DisplayAssembler.getInstance().addComponent(icon_, new Point(pixelX_, 
					pixelY_), JLayeredPane.MODAL_LAYER);
		}
		
		else if(playerNum == 3) {
			pixelX_ = DisplayAssembler.getTopLeftGo() + 2;
			pixelY_ = DisplayAssembler.getTopLeftGo()+ (int)(DisplayAssembler.getSpaceWidth() * .35);
			DisplayAssembler.getInstance().addComponent(icon_, new Point(pixelX_, 
					pixelY_), JLayeredPane.MODAL_LAYER);
		}
		
		else if(playerNum == 4) {
			pixelX_ = DisplayAssembler.getTopLeftGo() + 2;
			pixelY_ = DisplayAssembler.getTopLeftGo() + (int)(DisplayAssembler.getSpaceWidth() * .35) + pieceSeparation;
			DisplayAssembler.getInstance().addComponent(icon_, new Point(pixelX_, 
					pixelY_), JLayeredPane.MODAL_LAYER);
		}
		
		else if(playerNum == 5) {
			pixelX_ = DisplayAssembler.getTopLeftGo() + 2;
			pixelY_ = DisplayAssembler.getTopLeftGo()+ (int)(DisplayAssembler.getSpaceWidth() * .35);
			DisplayAssembler.getInstance().addComponent(icon_, new Point(pixelX_, 
					pixelY_), JLayeredPane.MODAL_LAYER);
		}
		
		else if(playerNum == 6) {
			pixelX_ = DisplayAssembler.getTopLeftGo() + 2;
			pixelY_ = DisplayAssembler.getTopLeftGo() + (int)(DisplayAssembler.getSpaceWidth() * .35) + pieceSeparation;
			DisplayAssembler.getInstance().addComponent(icon_, new Point(pixelX_, 
					pixelY_), JLayeredPane.MODAL_LAYER);
		}
		
		else if(playerNum == 7) {
			pixelX_ = DisplayAssembler.getTopLeftGo() + 2;
			pixelY_ = DisplayAssembler.getTopLeftGo()+ (int)(DisplayAssembler.getSpaceWidth() * .35);
			DisplayAssembler.getInstance().addComponent(icon_, new Point(pixelX_, 
					pixelY_), JLayeredPane.MODAL_LAYER);
		}
		
		else if(playerNum == 8) {
			pixelX_ = DisplayAssembler.getTopLeftGo() + 2;
			pixelY_ = DisplayAssembler.getTopLeftGo() + (int)(DisplayAssembler.getSpaceWidth() * .35) + pieceSeparation;
			DisplayAssembler.getInstance().addComponent(icon_, new Point(pixelX_, 
					pixelY_), JLayeredPane.MODAL_LAYER);
		}
		
		oldS = new Integer(0);
		newS = new Integer(0);
		moveFromTo = new LinkedList<Integer>();
		
		motionControl = new Semaphore(1);
	}
	
	public void move(final int numSpaces) {
		
		oldS = currentSpace_;
		currentSpace_ = (currentSpace_ + numSpaces) % TOTAL_SPACES;
		
		newS = currentSpace_;
		
		moveFromTo.add(oldS);
		moveFromTo.add(newS);
		
		new Thread("PieceMovement") {
			public void run() {
				try {
					motionControl.acquire();
					
					state_.move(Piece.this, Piece.this.moveFromTo.poll().intValue(), 
							Piece.this.moveFromTo.poll().intValue());
					
					motionControl.release();
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}.start();
	}
	
	public JLabel getIcon() {
		return icon_;
	}
	
	void changeState(PieceState newState) {
		state_ = newState;
	}
	
	public PieceState getState() {
		return state_;
	}
	
	public void removePiece() {
		DisplayAssembler.getInstance().removeComponent(icon_);
	}

	public void moveToSpace(int spaceNum) {

		int numSpaces = (spaceNum + TOTAL_SPACES - currentSpace_) % TOTAL_SPACES;
		move(numSpaces);
	}
}
